package com.qumitech.visualnovel.service.union.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qumitech.visualnovel.component.exception.BusinessException;
import com.qumitech.visualnovel.component.util.CommonUtil;
import com.qumitech.visualnovel.component.util.HttpInvokeUtil;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.ResultEnum;
import com.qumitech.visualnovel.datasource.console.UnionSysUserRoleDOMapper;
import com.qumitech.visualnovel.datasource.console.UnionUserInfoDOMapper;
import com.qumitech.visualnovel.model.dao.console.UnionUserInfoDO;
import com.qumitech.visualnovel.model.dao.console.UserInfo;
import com.qumitech.visualnovel.pubdef.constant.SqlConstant;
import com.qumitech.visualnovel.model.common.UrlConstant;
import com.qumitech.visualnovel.pubdef.dto.union.*;
import com.qumitech.visualnovel.service.union.UnionService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class UnionServiceImpl implements UnionService {

    @Autowired
    private UnionUserInfoDOMapper unionUserInfoDOMapper;

    @Autowired
    private  UnionSysUserRoleDOMapper unionSysUserRoleDOMapper;

    @Override
    public BaseRsp saveUnionConfig(UnionConfigSaveAdminDTO saveAdminDTO) {
        saveAdminDTO.setOperator(getActiveUserName());
        String url = UrlConstant.SERVER_URL + "/admin/union";
        String req = JSONObject.toJSONString(saveAdminDTO);
        String body = HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);
        return JSONObject.parseObject(body, BaseRsp.class);
    }

    @Override
    public BaseRsp updateUnionConfig(String unionId, UnionConfigSaveAdminDTO updateAdminDTO) {
        updateAdminDTO.setOperator(getActiveUserName());
        String url = UrlConstant.SERVER_URL + "/admin/union/" + unionId;
        String req = JSONObject.toJSONString(updateAdminDTO);
        String body = HttpInvokeUtil.httpPutJson(url, req, UrlConstant.DefaultEncode, null);
        return JSONObject.parseObject(body, BaseRsp.class);
    }

    @Override
    public BaseRsp listUnionConfig(UnionConfigQueryAdminDTO queryAdminDTO) {
        String url = UrlConstant.SERVER_URL + "/admin/union";
        JSONObject o = JSONObject.parseObject(JSONObject.toJSONString(queryAdminDTO));
        Map<String, Object> req = JSONObject.toJavaObject(o, Map.class);
        String body = HttpInvokeUtil.httpGet(url, req);
        return JSONObject.parseObject(body, BaseRsp.class);
    }

    @Override
    public void saveUnionUserInfo(UnionUserInfoSaveAdminDTO saveAdminDTO) {
        UnionUserInfoDO unionUserInfoDO = unionUserInfoDOMapper.selectSupervisorByUnionId(saveAdminDTO.getUnionId());
        if (unionUserInfoDO != null){
            throw new BusinessException(ResultEnum.UNION_ID_HAS_BIND_USER);
        }
        UnionUserInfoDO newUnionUserInfoDO = new UnionUserInfoDO();
        BeanUtils.copyProperties(saveAdminDTO, newUnionUserInfoDO);
        SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator();
        String salt = secureRandomNumberGenerator.nextBytes().toHex();
        Md5Hash md5 = new Md5Hash(newUnionUserInfoDO.getPassword(),newUnionUserInfoDO.getUsername()+salt,2);
        newUnionUserInfoDO.setPassword(md5.toHex());
        newUnionUserInfoDO.setSalt(salt);
        unionUserInfoDOMapper.insertSelective(newUnionUserInfoDO);
        newUnionUserInfoDO.setUid(Math.toIntExact(newUnionUserInfoDO.getId()));
        unionUserInfoDOMapper.updateByPrimaryKeySelective(newUnionUserInfoDO);
        //工会管理员和角色
        unionSysUserRoleDOMapper.bindUserSysRole(newUnionUserInfoDO.getUid(), 2);
    }

    @Override
    public void rmUnionUserInfo(Integer uid) {
        unionUserInfoDOMapper.updateDeleteFlag(uid, SqlConstant.IS_DELETED);
    }

    @Override
    public void updateUserInfo(Integer uid, String password, Byte deleteFlag) {
        UnionUserInfoDO unionConfigDO = unionUserInfoDOMapper.selectByUid(uid);
        unionConfigDO.setDeleteFlag(deleteFlag);
        if (password != null) {
            Md5Hash md5 = new Md5Hash(password, unionConfigDO.getUsername() + unionConfigDO.getSalt(), 2);
            unionConfigDO.setPassword(md5.toHex());
        }
        unionUserInfoDOMapper.updateByPrimaryKeySelective(unionConfigDO);
    }

    @Override
    public List<UnionUserInfoDTO> listUnionUserInfo(UnionUserInfoQueryAdminDTO queryAdminDTO) {
        List<String> unionIds = new ArrayList<>();
        Map<String, UnionConfigDTO> UnionConfigDTOMap = new HashMap<>();
        List<UnionUserInfoDTO> unionUserInfoDTOList = unionUserInfoDOMapper.listUnionUserInfo(queryAdminDTO);
        for(UnionUserInfoDTO unionUserInfoDTO: unionUserInfoDTOList) {
            unionIds.add(unionUserInfoDTO.getUnionId());
        }
        UnionConfigQueryAdminDTO configQueryAdminDTO = new UnionConfigQueryAdminDTO();
        configQueryAdminDTO.setOffset(0);
        configQueryAdminDTO.setLimit(unionIds.size());
        configQueryAdminDTO.setUnionIds(CommonUtil.join(",", unionIds));
        BaseRsp baseRsp = listUnionConfig(configQueryAdminDTO);
        List<UnionConfigDTO> unionConfigDTOList = JSONArray.parseArray((((JSONObject) baseRsp.getData()).getJSONArray("union_config").toString()), UnionConfigDTO.class);
        for(UnionConfigDTO unionConfigDTO: unionConfigDTOList){
            UnionConfigDTOMap.put(unionConfigDTO.getUnionId(), unionConfigDTO);
        }

        for(UnionUserInfoDTO unionUserInfoDTO: unionUserInfoDTOList) {
            UnionConfigDTO unionConfigDTO = UnionConfigDTOMap.get(unionUserInfoDTO.getUnionId());
            unionUserInfoDTO.setUnionName(unionConfigDTO.getUnionName());
            unionUserInfoDTO.setAdminName(unionConfigDTO.getAdminName());
        }
        return unionUserInfoDTOList;
    }

    @Override
    public Integer countUnionUserInfo(UnionUserInfoQueryAdminDTO queryAdminDTO) {
        return unionUserInfoDOMapper.countUnionUserInfo(queryAdminDTO);
    }

    @Override
    public BaseRsp listUnionAnchorApply(UnionAnchorApplyQueryAdminDTO queryAdminDTO) {
        String url = UrlConstant.SERVER_URL + "/admin/union/";
        JSONObject o = JSONObject.parseObject(JSONObject.toJSONString(queryAdminDTO));
        Map<String, Object> req = JSONObject.toJavaObject(o, Map.class);
        String body = HttpInvokeUtil.httpGet(url, req);
        return JSONObject.parseObject(body, BaseRsp.class);
    }

    public String findUnionIdByUnionName(UnionUserInfoQueryAdminDTO queryAdminDTO){
        if (queryAdminDTO.getUnionName() != null)
        {
            UnionConfigQueryAdminDTO configQueryAdminDTO = new UnionConfigQueryAdminDTO();
            configQueryAdminDTO.setUnionName(queryAdminDTO.getUnionName());
            configQueryAdminDTO.setOffset(0);
            configQueryAdminDTO.setLimit(1);
            BaseRsp baseRsp = listUnionConfig(configQueryAdminDTO);
            List<UnionConfigDTO> unionConfigDTOList = JSONArray.parseArray((((JSONObject) baseRsp.getData()).getJSONArray("union_config").toString()), UnionConfigDTO.class);
            if (!unionConfigDTOList.isEmpty()){
                return unionConfigDTOList.get(0).getUnionId();
            }
        }
        return null;
    }

    private String getActiveUserName(){
        Subject subject = SecurityUtils.getSubject();
        UserInfo activeUser = (UserInfo) subject.getPrincipal();
        return activeUser.getUsername();
    }


}
